#include <pthread.h>
#include <time.h>

#include "nvcprocess.h"

#define MAX_PACKET_SIZE 2048
#define MAX_PACKET_NUM 0x1000 //packet buffer size = 4k
#define MAX_NUM_MASK 0x0FFF

unsigned char buffer[MAX_PACKET_NUM][MAX_PACKET_SIZE];
unsigned short read_position,write_position;
unsigned char thread_status = THREAD_STATUS_DEAD;
pthread_t       tid; 

unsigned char get_thread_status()
{
	return thread_status;
}
void set_thread_status(unsigned char status)
{
	thread_status = status;
}
int start_thread()
{
	int err = 0;
	pthread_attr_t  pattr;
	pthread_attr_init(&pattr);

	read_position = 0;
	write_position = 0;
	if((err = pthread_create(&tid, &pattr, &thread_func, NULL)))
		return err;

	return 0;
}
void stop_thread()
{
	pthread_join(tid, NULL);
}
void * thread_func(void * arg)
{
	int rindex,windex;
	int cnt_to_write;
	int cnt_received;
	struct timeval rec_time;

	set_thread_status(THREAD_STATUS_ALIVE);
	while(get_thread_status() == THREAD_STATUS_ALIVE)
	{
		rindex = read_position & MAX_NUM_MASK;
		windex = write_position & MAX_NUM_MASK;
		if( windex >= rindex)
			cnt_to_write = rindex + MAX_PACKET_NUM - windex;
		else
			cnt_to_write = rindex - windex;

		if((cnt_received = receive(buffer[windex] + 12, MAX_PACKET_SIZE)) > 0)
		{
			buffer[windex][0] = 0x02;
			*((unsigned short *)(buffer[windex] + 1)) = cnt_received & 0xFFFF;
			buffer[windex][11] = 0x00;
			buffer[windex][12 + cnt_received] = 0x03;
			if(cnt_to_write > 0)
			{
				gettimeofday(&rec_time, NULL);
				*((unsigned int *)(buffer[windex] + 3)) = rec_time.tv_sec;
				*((unsigned int *)(buffer[windex] + 7)) = rec_time.tv_usec;
				write_position++;
			}			
		}
		else if(cnt_received == 0)
			usleep(500);
		else
		{
			//write_log("error while")
			break;
		}
	}

	set_thread_status(THREAD_STATUS_DEAD);
}

int get_packet(unsigned char ** buff)
{
	int rindex,windex;
	int cnt_to_read, packet_len;
	/*if(buff == NULL)
		return 0;*/
	rindex = read_position & MAX_NUM_MASK;
	windex = write_position & MAX_NUM_MASK;
	if(rindex > windex)
		cnt_to_read = windex + MAX_PACKET_NUM - rindex;
	else
		cnt_to_read = windex - rindex;
	if(cnt_to_read > 0)
	{
		packet_len = *((unsigned short *)(buffer[rindex] + 1)) + 13;
		/*memcpy(buff, buffer[rindex], packet_len);*/
		*buff = buffer[rindex];
		read_position++;
		return packet_len;
	}
	return 0;
}